1 /****************************** Module Header ******************************\
2 * Module Name: FilePropSheetExt.cpp
3 * Project: ATLShellExtPropSheetHandler
4 * Copyright (c) Microsoft Corporation.
6 * The implementation of CFilePropSheetExt for the FilePropSheet property
7 * sheet handler. FilePropSheetExt adds a property page with the subject
8 * "All-In-One Code Framework" to the property dialogs of all file classes in
9 * Windows Explorer. The property page displays the name of the first selected
10 * file. It also has a button "Simulate Property Changing" to simulate the
11 * change of properties that activates the "Apply" button of the property
14 * This source is subject to the Microsoft Public License.
15 * See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
16 * All other rights reserved.
18 * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
19 * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
21 \***************************************************************************/
23 #pragma region Includes
25 #include "FilePropSheetExt.h"
29 INT_PTR CALLBACK
FilePropPageDlgProc(HWND
, UINT
, WPARAM
, LPARAM
);
30 UINT CALLBACK
FilePropPageCallbackProc(HWND
, UINT
, LPPROPSHEETPAGE
);
33 /////////////////////////////////////////////////////////////////////////////
34 // CFilePropSheetExt IShellExtInit methods.
38 // FUNCTION: CFilePropSheetExt::Initialize(LPCITEMIDLIST, LPDATAOBJECT,
41 // PURPOSE: Initializes a property sheet extension, shortcut menu extension,
42 // or drag-and-drop handler.
44 IFACEMETHODIMP
CFilePropSheetExt::Initialize(
45 LPCITEMIDLIST pidlFolder
, LPDATAOBJECT pDataObj
, HKEY hProgID
)
52 FORMATETC fe
= { CF_HDROP
, NULL
, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
};
55 // pDataObj contains the objects being acted upon. In this example,
56 // we get an HDROP handle for enumerating the selected files.
57 if (FAILED(pDataObj
->GetData(&fe
, &stm
)))
60 // Get an HDROP handle.
61 HDROP hDrop
= (HDROP
)GlobalLock(stm
.hGlobal
);
64 ReleaseStgMedium(&stm
);
68 // Determine how many files are involved in this operation
69 UINT nFiles
= DragQueryFile(hDrop
, 0xFFFFFFFF, NULL
, 0);
72 GlobalUnlock(stm
.hGlobal
);
73 ReleaseStgMedium(&stm
);
77 // Get the name of the first file and store it in m_szFileName
78 if (0 == DragQueryFile(hDrop
, 0, m_szFileName
, MAX_PATH
))
80 GlobalUnlock(stm
.hGlobal
);
81 ReleaseStgMedium(&stm
);
87 // Enumerates through the selected files and directories
88 //TCHAR szFileName[MAX_PATH];
89 //for (UINT i = 0; i < nFiles; i++)
91 // // Get the next filename
92 // if (0 == DragQueryFile(hDrop, i, szFileName, MAX_PATH))
99 GlobalUnlock(stm
.hGlobal
);
100 ReleaseStgMedium(&stm
);
102 // If any value other than S_OK is returned from
103 // IShellExtInit::Initialize, the context menu is not displayed.
108 /////////////////////////////////////////////////////////////////////////////
109 // CFilePropSheetExt IShellPropSheetExt methods.
113 // FUNCTION: CFilePropSheetExt::AddPages(LPFNADDPROPSHEETPAGE, LPARAM)
115 // PURPOSE: Adds one or more pages to a property sheet that the Shell
116 // displays for a file object. The Shell calls this method for
117 // each property sheet handler registered to the file type.
119 IFACEMETHODIMP
CFilePropSheetExt::AddPages(
120 LPFNADDPROPSHEETPAGE lpfnAddPageProc
, LPARAM lParam
)
123 HPROPSHEETPAGE hPage
;
125 // Set up the PROPSHEETPAGE struct
126 ZeroMemory(&psp
, sizeof(PROPSHEETPAGE
));
127 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
128 psp
.dwFlags
= PSP_USETITLE
| PSP_USECALLBACK
;
129 psp
.hInstance
= _AtlBaseModule
.GetResourceInstance();
130 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_FILE_PROPPAGE
);
132 psp
.pszTitle
= _T("All-In-One Code Framework");
133 psp
.pfnDlgProc
= (DLGPROC
)FilePropPageDlgProc
;
134 psp
.pcRefParent
= NULL
;
135 psp
.pfnCallback
= FilePropPageCallbackProc
;
136 // Pass the object pointer to the property page
137 psp
.lParam
= (LPARAM
)this;
139 // Create a property sheet page and get the handle.
140 hPage
= CreatePropertySheetPage(&psp
);
144 // The property page is then added to the property sheet by calling
145 // the callback function passed to IShellPropSheetExt::AddPages in
146 // the lpfnAddPage parameter.
147 if (lpfnAddPageProc(hPage
, lParam
))
149 // By default, after AddPages returns, the shell releases its
150 // IShellPropSheetExt interface and the property page cannot
151 // access the extension object. However, it is sometimes desirable
152 // to be able to use the extension object, or some other object,
153 // from the property page. So we increase the reference count and
154 // maintain this object until the page is released in
155 // PropPageCallbackProc where we call Release upon the extension.
160 DestroyPropertySheetPage(hPage
);
166 return E_OUTOFMEMORY
;
169 // If any value other than S_OK is returned from
170 // IShellPropSheetExt::AddPages, the property sheet is not displayed.
175 /////////////////////////////////////////////////////////////////////////////
176 // CFilePropSheetExt dialog/callback procs
179 #define THIS_POINTER_PROP _T("ThisPointerProperty")
183 // FUNCTION: OnInitFilePropPageDialog(HWND, HWND, LPARAM)
185 // PURPOSE: Process the WM_INITDIALOG message of the property page.
187 BOOL
OnInitFilePropPageDialog(HWND hWnd
, HWND hWndFocus
, LPARAM lParam
)
189 // Get the pointer to the object. This is contained in the LPARAM of
190 // the PROPSHEETPAGE structure.
191 LPPROPSHEETPAGE pPage
= (LPPROPSHEETPAGE
)lParam
;
194 // Access the property sheet extension from property page
195 CFilePropSheetExt
* pPropSheetExt
= (CFilePropSheetExt
*)pPage
->lParam
;
198 HWND hFileName
= GetDlgItem(hWnd
, IDC_FILENAME_STATIC
);
199 SetWindowText(hFileName
, pPropSheetExt
->m_szFileName
);
201 // Store the object pointer with this particular page dialog.
202 SetProp(hWnd
, THIS_POINTER_PROP
, (HANDLE
)pPropSheetExt
);
211 // FUNCTION: OnFilePropPageApply(HWND, PSHNOTIFY*)
213 // PURPOSE: OnFilePropPageApply is called for the property page when user
214 // clicks on the Apply or OK button on the property sheet.
216 BOOL
OnFilePropPageApply(HWND hWnd
, PSHNOTIFY
* phdr
)
218 // Get the property sheet extension object pointer that was stored
219 // in the page dialog. (see OnInitPropPageDialog)
220 CFilePropSheetExt
*pPropSheetExt
= (CFilePropSheetExt
*)GetProp(hWnd
,
223 // Access the property sheet extension object
226 // Return PSNRET_NOERROR to allow the property dialog to close if the
228 SetWindowLong(hWnd
, DWL_MSGRESULT
, PSNRET_NOERROR
);
235 // FUNCTION: OnFilePropPageDestroy(HWND)
237 // PURPOSE: Process the WM_DESTROY message of the property page.
239 void OnFilePropPageDestroy(HWND hWnd
)
241 // Remove the property from the page.
242 RemoveProp(hWnd
, THIS_POINTER_PROP
);
247 // FUNCTION: FilePropPageDlgProc(HWND, UINT, WPARAM, LPARAM)
249 // PURPOSE: Processes messages for the property page.
251 INT_PTR CALLBACK
FilePropPageDlgProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
,
257 return OnInitFilePropPageDialog(hWnd
, (HWND
)wParam
, lParam
);
261 switch (LOWORD(wParam
))
263 case IDC_CHANGEFILEPROP_BN
:
264 // Simulate property changing.
265 // Inform the property sheet to enable the Apply button
266 SendMessage(GetParent(hWnd
), PSM_CHANGED
, (WPARAM
)hWnd
, 0);
274 switch (((LPNMHDR
)lParam
)->code
)
277 return OnFilePropPageApply(hWnd
, (PSHNOTIFY
*)lParam
);
283 OnFilePropPageDestroy(hWnd
);
287 return FALSE
; // Let system deal with other messages
292 // FUNCTION: FilePropPageCallbackProc(HWND, UINT, LPPROPSHEETPAGE)
294 // PURPOSE: Specifies an application-defined callback function that a
295 // property sheet calls when a page is created and when it is
296 // about to be destroyed. An application can use this function to
297 // perform initialization and cleanup operations for the page.
299 UINT CALLBACK
FilePropPageCallbackProc(HWND hWnd
, UINT uMsg
,
300 LPPROPSHEETPAGE ppsp
)
305 // Must return TRUE to enable the page to be created.
310 // Release the property sheet extension object. This is called
311 // even if the property page was never actually displayed.
312 CFilePropSheetExt
*pPropSheetExt
= (CFilePropSheetExt
*)ppsp
->lParam
;
314 if (pPropSheetExt
!= NULL
)
316 pPropSheetExt
->Release();